package com.hxkj.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hxkj.dao.*;
import com.hxkj.domain.enums.SiteExceptionEnum;
import com.hxkj.domain.enums.SiteStatusEnum;
import com.hxkj.domain.enums.UserExceptionEnum;
import com.hxkj.domain.po.*;
import com.hxkj.service.AuthRoleService;
import com.hxkj.service.AuthSiteService;
import com.hxkj.service.FunctionLibraryService;
import com.hxkj.utils.StrSliptUtils;
import com.platform.common.domain.exception.CustomMessageException;
import com.platform.common.domain.result.ResultDataStruct;
import com.platform.common.domain.result.ResultMessageStruct;
import com.platform.common.domain.to.PageTo;
import com.platform.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 站点实现类
 * <p>
 * Created by zzx on 2018/5/19.
 */
@Service
@Slf4j
public class SiteServiceImpl implements AuthSiteService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SiteServiceImpl.class);

    @Autowired
    private SiteDao siteDao;

    @Autowired
    private UserSiteDao userSiteDao;

    @Autowired
    private AuthFunctionDao authFunctionDao;

    @Autowired
    private FunctionDao functionDao;

    @Autowired
    private AuthRoleDao authRoleDao;

    @Autowired
    private AuthRoleService authRoleService;

    @Autowired
    private AuthUserRoleAppDao authUserRoleAppDao;

    @Autowired
    private AuthRoleFunctionDao authRoleFunctionDao;

    @Autowired
    private AuthUserDao authUserDao;

    @Autowired
    private InitializeFunctionService initializeFunctionService;

    @Autowired
    private FunctionLibraryService functionLibraryService;

    @Autowired
    private FunctionLibraryDao functionLibraryDao;

    /**
     * 获取一个站点列表
     *
     * @param
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<Site> getSiteList(Site site, PageTo pageParam) throws Exception {
        Page<Site> page = PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());

        List<Site> siteList = new ArrayList<>();
        try {
            if (site.getUserId().equals(1L)) {
                site.setDelTag((byte) 0);
                //查看全部站点列表(不包含主站）
                siteList = siteDao.getSiteList(site);
            } else {
                //查看该用户已分配的站点
                siteList = siteDao.getSiteByUserId(site);
            }
            //Mr.zheng:将站点可分配的功能信息存入
            FunctionLibrary functionLibrary = new FunctionLibrary();

            for (Site st : siteList) {
                List<Long> list = new ArrayList<>();
                list = setFunctionLibraryListToSite(list, st, functionLibrary);//异步存入站点可分配的功能
                st.setChildren(list);
            }
            PageInfo<Site> pageInfo = new PageInfo<>(page);
            pageInfo.setList(siteList);
            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("查询站点列表错误");
        }
        return new PageInfo<>(page);
    }

    /**
     * @return void
     * @author Mr.zheng
     * @Description setFunctionLibraryListToSite 异步为站点信息存入可分配的功能信息
     * @Date 9:19 2018/8/29
     * @Param [site, functionLibrary]
     **/
    @Async
    protected List<Long> setFunctionLibraryListToSite(List<Long> list, Site site, FunctionLibrary functionLibrary) throws Exception {
        functionLibrary.setSiteId(site.getSiteId());
        List<FunctionLibrary> functionLibraryList = functionLibraryDao.getShowFunctionLibrarieIdList(functionLibrary);
        for (FunctionLibrary function : functionLibraryList) {
            list.add(function.getId());
        }
        return list;
    }

    @Override
    public ResultDataStruct<List<Site>> getSwitcherList(Site site) throws Exception {
        ResultDataStruct<List<Site>> resultDataStruct = new ResultDataStruct();
        List<Site> siteList = new ArrayList<>();
        try {
            if (site.getUserId().equals(1L)) {
                site.setDelTag((byte) 0);
                //查看全部站点列表(包含主站）
                siteList = siteDao.getSwitcherSiteList(site);
            } else {
                //查看该用户已分配的站点
                siteList = siteDao.getSwitcherByUserId(site);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("查询站点列表错误");
            resultDataStruct.setCode(SiteExceptionEnum.SITE_GET_ERROR.getCode());
            resultDataStruct.setMessage(SiteExceptionEnum.SITE_GET_ERROR.getMsg());
            return resultDataStruct;
        }
        resultDataStruct.setCode(SiteStatusEnum.SUCCESS.getCode());
        resultDataStruct.setMessage(SiteStatusEnum.SUCCESS.getMsg());
        resultDataStruct.setData(siteList);
        return resultDataStruct;
    }

    /**
     * 获取一个站点信息
     *
     * @param site
     * @return
     * @throws Exception
     */
    @Override
    public ResultDataStruct<Site> getSiteFromCache(Site site) {
        ResultDataStruct resul = new ResultDataStruct();
        Site sites;
        try {
            //通过站点Id查询站点信息
            sites = siteDao.get(site.getSiteId());
        } catch (Exception e) {
            e.printStackTrace();
            resul.setCode(SiteExceptionEnum.SITE_GET_ERROR.getCode());
            resul.setMessage(SiteExceptionEnum.SITE_GET_ERROR.getMsg());
            return resul;
        }
        resul.setCode(SiteStatusEnum.SUCCESS.getCode());
        resul.setMessage(SiteStatusEnum.SUCCESS.getMsg());
        resul.setData(sites);

        return resul;
    }


    @Override
    public void updateSite(Site site) throws Exception {
        Site siteName = siteDao.selectSiteName(site);
        if (siteName != null) {
            throw new CustomMessageException(SiteExceptionEnum.MODIFLY_SITE_ERROR.getCode(), SiteExceptionEnum.MODIFLY_SITE_ERROR.getMsg());
        }
        // 修改站点基本信息
        siteDao.update(site);
        // 修改站点功能
        if (StringUtils.isNotBlank(site.getIds())) {
            FunctionLibrary functionLibrary = new FunctionLibrary();
            functionLibrary.setSiteId(site.getSiteId());
            functionLibrary.setIds(site.getIds());
            functionLibraryService.functionToSite(functionLibrary);
        }

    }

    /**
     * 批量删除站点信息
     *
     * @param site
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct deleteSite(Site site) throws Exception {
        ResultMessageStruct result = new ResultMessageStruct();
        //解析批量操作的功能id
        String[] siteIds = site.getSiteIds().split(",");
        try {
            //遍历id,进行循环修改 执行删除
            for (int i = 0; i < siteIds.length; i++) {

                //从 t_site (站点表)中删除站点信息
                siteDao.delete(Long.valueOf(siteIds[i]));
                //从 t_user_site（用户与站点关联）中删除关联信息
                userSiteDao.deleteUserSiteBySiteId(Long.valueOf(siteIds[i]));
                //从 t_auth_function（功能表）中删除初始化的子站功能
                authFunctionDao.deleteFunctionBySiteId(Long.valueOf(siteIds[i]));
                //查询角色Id
                AuthRole role = authRoleDao.findRoleBySiteId(Long.valueOf(siteIds[i]));
                if (role != null) {
                    //t_auth_user_role_app(子站用户与子站角色关联) 中删除 用户与角色关联
                    authUserRoleAppDao.deleteUserRoleAppByRoleId(role.getRoleId());
                    //从 t_auth_role_function （角色与功能关联）中 删除子站 中的 角色与功能关联
                    authRoleFunctionDao.deleteFunctionByRoleId(role.getRoleId());
                    //从 t_auth_role（角色表） 中删除该子站的角色
                    authRoleDao.deleteRoleByRoleId(role.getRoleId());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(SiteExceptionEnum.SITE_REMOVE_ERROR.getCode());
            result.setMessage(SiteExceptionEnum.SITE_REMOVE_ERROR.getMsg());
            return result;
        }
        result.setCode(SiteStatusEnum.SUCCESS.getCode());
        result.setMessage(SiteStatusEnum.SUCCESS.getMsg());
        return result;
    }

    /**
     * 新增一个站点信息
     *
     * @param site
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct saveSite(Site site) throws Exception {
        ResultMessageStruct result = new ResultMessageStruct();
        // 默认返回状态为成功
        result.setCode(SiteStatusEnum.SUCCESS.getCode());
        result.setMessage(SiteStatusEnum.SUCCESS.getMsg());
        try {

            Site siteName = new Site();
            siteName.setSiteName(site.getSiteName());
            siteName.setDelTag((byte) 0);
            Site siteNames = siteDao.selectSiteName(siteName);
            // 判断站点是否已经存在，如果存在则不允许重复添加
            if (siteNames != null) {
                result.setCode(SiteExceptionEnum.MODIFLY_SITE_ERROR.getCode());
                result.setMessage(SiteExceptionEnum.MODIFLY_SITE_ERROR.getMsg());
                return result;
            }
            // 新增一个子站点
            site.setCreateTime(System.currentTimeMillis());
            site.setDelTag((byte) 0);
            siteDao.save(site);

            if (StringUtils.isNotBlank(site.getIds())) {
                FunctionLibrary functionLibrary = new FunctionLibrary();
                functionLibrary.setSiteId(site.getSiteId());
                functionLibrary.setIds(site.getIds());
                functionLibraryService.functionToSite(functionLibrary);
            }

            // 获取上面新增子站点（需要用到子站点id）
//            Site SiteId = siteDao.selectSiteName(siteName);

            //首先初始化一条父级菜单(子站平台管理)
//            AuthFunction system = initializeFunctionService.initializeSiteManger(SiteId.getSiteId());
//            authFunctionDao.save(system);

           // 根据子站siteId 查询出 父级菜单的id (子菜单初始化需要关联父级id)
//            AuthFunction function = new AuthFunction();
//            function.setSiteId(SiteId.getSiteId());
//            AuthFunction authFunction = functionDao.queryAuthFunction(function);

            // 1 初始化菜单
            //Mr.zheng:注释掉初始化功能，改为角色控制权限
//            initializeFunctionService.initializeFuncition(SiteId.getSiteId(), authFunction.getFunctionId());

            // 2 初始化子站角色（超级管理员）
            AuthRole authRole = initializeFunctionService.initializeAuthRole(site);
            authRoleDao.save(authRole);

            // 3 查询出角色id
            AuthRole role = authRoleDao.findRoleBySiteId(site.getSiteId());

            // 4 根据 siteId 查询出子站所有得菜单，并以逗号拼接 功能Id
            AuthFunction praraAuthFunction = new AuthFunction();
            praraAuthFunction.setSiteId(site.getSiteId());
            List<AuthFunction> sites1 = authFunctionDao.get(praraAuthFunction);
            String functionIds = "";
            for (int i = 0; i < sites1.size(); i++) {
                if (i < sites1.size() - 1) {
                    functionIds = functionIds + String.valueOf(sites1.get(i).getFunctionId()) + ",";
                } else {
                    functionIds = functionIds + String.valueOf(sites1.get(i).getFunctionId());
                }

            }
            AuthRole authRole1 = new AuthRole();
            authRole1.setSiteId(site.getSiteId());
            authRole1.setRoleId(role.getRoleId());
            authRole1.setFunctionIds(functionIds);

            // 5 为子站超级管理员角色 分配 功能
         //   authRoleService.saveAllocationFunction(authRole1);

            // 6 创建子站点时 给主站超级管理员权限关联 用户角色
            AuthUserRoleApp authUserRoleApp = initializeFunctionService.initializeAuthUserRoleApp(role);
            authUserRoleAppDao.save(authUserRoleApp);

            // 7 创建子站点时 给主站超级管理员与子站关联  用户站点
            UserSite userSite = initializeFunctionService.initializeUserSite(site.getSiteId());
            userSiteDao.save(userSite);


        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(SiteExceptionEnum.SITE_ADD_ERROR.getCode());
            result.setMessage(SiteExceptionEnum.SITE_ADD_ERROR.getMsg());
            return result;
        }
        return result;
    }

    /**
     * 实时刷新站点信息
     *
     * @param siteId
     * @return
     * @throws Exception
     */
    @Override
    public Site getSiteRefresh(Long siteId) throws Exception {
        return siteDao.get(siteId);
    }

    @Override
    //修改数据，注解开启事务
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct saveUserSite(AuthUser authUser) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultDataStruct<>();
        try {
            UserSite userSite = new UserSite();
            AuthUserRoleApp authUserRoleApp = new AuthUserRoleApp();
            // Mr.zheng: 判断用户是否为停用状态，如果停用无法分配站点
            if (authUserDao.getUserByUserId(authUser.getUserId()).getUserStatus().equals((byte) 1)) {
                resultMessageStruct.setCode(UserExceptionEnum.STOP_USER_NOT_SITE.getCode());
                resultMessageStruct.setMessage(UserExceptionEnum.STOP_USER_NOT_SITE.getMsg());
                return resultMessageStruct;
            }
            //Mr.zheng:清除用户名下所有关联子站
            userSite.setUserId(authUser.getUserId());
            userSiteDao.deleteUserSite(userSite);
            //Mr.zheng:清除用户名下所有角色关联
            authUserRoleApp.setUserId(authUser.getUserId());
            authUserRoleAppDao.deleteUserRoleByUserId(authUserRoleApp);
            //Mr.zheng:将用户关联角色属性置为未关联
            AuthUser aut = new AuthUser();
            aut.setUserId(authUser.getUserId());
            aut.setRoleTag(0);
            authUserDao.update(aut);
            //Mr.zheng:将站点ID字符串切割遍历
            String[] str = StrSliptUtils.sliptArray(authUser.getSiteIds());
            if (str.length < 0) {
                resultMessageStruct.setCode(UserExceptionEnum.PLEASE_SELECT_SITE.getCode());
                resultMessageStruct.setMessage(UserExceptionEnum.PLEASE_SELECT_SITE.getMsg());
                return resultMessageStruct;
            }
            int code = 0;
            //Mr.zheng:将userSite对象添加
            for (String s : str) {
                Long siteId = Long.valueOf(s);
                //Mr.zheng:判断该站点ID是否存在
                if (siteDao.get(siteId) == null) {
                    resultMessageStruct.setCode(UserExceptionEnum.SITE_NOT_MSG.getCode());
                    resultMessageStruct.setMessage(UserExceptionEnum.SITE_NOT_MSG.getMsg());
                    return resultMessageStruct;
                }
                UserSite userSite1 = new UserSite();
                userSite1.setUserId(authUser.getUserId());
                userSite1.setSiteId(siteId);
                userSite1.setDelTag(0L);
                code = userSiteDao.save(userSite1);
                //Mr.zheng:分配站点以后 为该用户分配当前站点的超级管理员角色,平台除外
                if (siteId != 0) {
                    setRoleToUser(authUser, siteId);
                }
            }
            if (code == 0) {
                resultMessageStruct.setCode(UserExceptionEnum.SITE_TO_USER_ERROR.getCode());
                resultMessageStruct.setMessage(UserExceptionEnum.SITE_TO_USER_ERROR.getMsg());
                return resultMessageStruct;
            }
            resultMessageStruct.setCode(200);
            resultMessageStruct.setMessage("分配站点成功");
            return resultMessageStruct;
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(UserExceptionEnum.SITE_TO_USER_ERROR.getCode());
            resultMessageStruct.setMessage(UserExceptionEnum.SITE_TO_USER_ERROR.getMsg());
            return resultMessageStruct;
        }
    }

    //Mr.zheng 分配站点以后 为该用户分配当前站点的超级管理员角色
    private void setRoleToUser(AuthUser authUser, Long siteId) throws Exception {
        //Mr.zheng:更改用户标识为已关联角色
        AuthUser user = new AuthUser();
        user.setUserId(authUser.getUserId());
        user.setRoleTag(1);
        authUserDao.updateUser(user);
        //Mr.zheng: 获取子站超级管理员角色编号
        AuthRole siteRole = authRoleDao.getRoleBySiteId(siteId);
        AuthUserRoleApp authUserRoleApp = new AuthUserRoleApp();
        authUserRoleApp.setUserId(authUser.getUserId());
        authUserRoleApp.setRoleId(siteRole.getRoleId());
        authUserRoleApp.setAppId(1L);
        authUserRoleApp.setCreateTime(System.currentTimeMillis());
        authUserRoleAppDao.saveAuthUserRole(authUserRoleApp);
    }

    @Override
    public ResultDataStruct<AllocationSite> getUserSiteList(Long uid) throws Exception {
        ResultDataStruct resultDataStruct = new ResultDataStruct();
        try {
            AllocationSite allocationSite = new AllocationSite();
            List<Long> siteIdList = new ArrayList<>();
            UserSite userSite = new UserSite();
            userSite.setUserId(uid);
            //Mr.zheng:获取该用户的站点ID
            List<UserSite> userSiteList = userSiteDao.get(userSite);
            for (UserSite usite : userSiteList) {
                //Mr.zheng:如果该站点id为0则不显示
                if (!usite.getSiteId().equals(0L)) {
                    int count = siteDao.getCountSite(usite.getSiteId());
                    //Mr.zheng:查看该站点是否被停用
                    if (count != 0) {
                        siteIdList.add(usite.getSiteId());
                    }
                }
            }
            //Mr.zheng:获取所有站点
            List<Site> sites = siteDao.getShowSiteList(new Site());
            allocationSite.setAllSite(sites);
            allocationSite.setSiteIdList(siteIdList);
            resultDataStruct.setCode(200);
            resultDataStruct.setData(allocationSite);
            resultDataStruct.setMessage("用户站点获取成功");
            return resultDataStruct;
        } catch (Exception e) {
            e.printStackTrace();
            resultDataStruct.setCode(UserExceptionEnum.GET_USER_SITE_ERROR.getCode());
            resultDataStruct.setMessage(UserExceptionEnum.GET_USER_SITE_ERROR.getMsg());
            return resultDataStruct;
        }
    }

    @Override
    public ResultMessageStruct SiteSort(Site site) throws Exception {
        ResultMessageStruct result = new ResultMessageStruct();
        //解析批量操作的功能id
        if (site.getSiteIds() == null) {
            result.setCode(SiteExceptionEnum.SITE_NOT_ID.getCode());
            return result;
        }
        String[] siteIds = site.getSiteIds().split(",");
        for (int i = 0; i < siteIds.length; i++) {
            Site sites = new Site();
            sites.setSiteId(Long.valueOf(siteIds[i]));
            sites.setSortNumber((long) i);
            siteDao.update(sites);
        }
        result.setCode(SiteStatusEnum.SUCCESS.getCode());
        result.setMessage(SiteStatusEnum.SUCCESS.getMsg());
        return result;
    }

    @Override
    public List<Site> getList(Site site) throws Exception {
        return siteDao.getList(site);
    }

    @Override
    public String getSiteLogo(Long siteId) throws Exception {
        return siteDao.getSiteLogo(siteId);
    }

    @Override
    public List<Site> getSiteInfoList(Site site, PageTo pageParam) {
        Integer pageNum = pageParam.getPageNum() == null ? 0 : pageParam.getPageNum();
        Integer pageSize = pageParam.getPageSize() == null ? 0 : pageParam.getPageSize();;
        if(0 == pageNum && 0 == pageSize){
            //不分页
            return siteDao.getSiteInfoList(site);
        }
        //分页查询
        pageNum = pageNum == 0 ? 1 : pageNum;
        pageSize = pageSize == 0 ? 10 : pageSize;
        PageHelper.startPage(pageNum, pageSize);
        List<Site> siteList = siteDao.getSiteInfoList(site);
        return siteList;
    }
}